home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / PCCardNetworkSample / MyRegisterPort.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  10.2 KB  |  398 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MyRegisterPort.c
  3.  
  4.     Contains:    Contains the custom routines for registering an offlineing an OT Port
  5.                 See the PortScanner.c file for an explanation of the call
  6.  
  7.     Written by:     
  8.  
  9.     Copyright:    Copyright © 1998-1999 by Apple Computer, Inc., All Rights Reserved.
  10.  
  11.                 You may incorporate this Apple sample source code into your program(s) without
  12.                 restriction. This Apple sample source code has been provided "AS IS" and the
  13.                 responsibility for its operation is yours. You are not permitted to redistribute
  14.                 this Apple sample source code as "Apple sample source code" after having made
  15.                 changes. If you're going to re-distribute the source, we require that you make
  16.                 it clear in the source that the code was descended from Apple sample source
  17.                 code, but that you've made changes.
  18.  
  19.     Change History (most recent first):
  20.                 8/16/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  21.                 
  22.  
  23. */
  24.  
  25.  
  26. #pragma export on
  27.  
  28. //----------------------------------------------------------------------
  29.  
  30. #define    DEBUG                    1
  31. //----------------------------------------------------------------------
  32.  
  33. #include  <OpenTptModule.h>
  34. #include  <OpenTptLinks.h>
  35. #include <PCCardEnablerPlugin.h>
  36. #include <PCCardTuples.h>
  37. #include <Gestalt.h>
  38. #include <DriverFamilyMatching.h>
  39. #include "EnablerSample.h"
  40. #include "MyRegisterPort.h"
  41.  
  42.  
  43. static Boolean OfflinePortExists(RegEntryID *deviceRef, DriverDescription *dd, UInt32 socketNum);
  44. static OSStatus SetPortConfiguredProperty (RegEntryID *deviceRef);
  45.  
  46. /*
  47.     The OfflinePortExists call is used to offline a port
  48.     where the assumption is that the deviceRef for the device
  49.     in the NameRegistry is stored in the fContext field of the
  50.     portRecord.  This routine searches the ports for an entry which
  51.     has a matching deviceRef value and unregisters the port.
  52.     
  53.     Assumes that there is an existing port that has as it's fContext
  54.     value, the same as *deviceRef, so that the value can be matched.
  55. */
  56.  
  57. static Boolean OfflinePortExists(RegEntryID *deviceRef, DriverDescription *dd, UInt32 socketNum)
  58. {
  59.     DriverServiceInfo    *dsi;
  60.     TPortRecord            *portRecord;
  61.     UInt32                index;
  62.     UInt32                busType;
  63.     size_t                idx;
  64.     OSStatus            err;
  65.     Boolean                foundOne;
  66.     
  67.  
  68. #if DEBUG
  69.     DebugStr("\p about to check for offlined ports");
  70. #endif
  71.  
  72.     index = 0;
  73.     while (portRecord = OTGetIndexedPort(index))
  74.     {
  75.         index++;
  76.             
  77.         busType = OTGetBusTypeFromPortRef(portRecord->fRef);
  78.         if (busType == kOTPCCardBus)
  79.         {
  80. #if DEBUG
  81.             DebugStr("\p PCCard port found");                    
  82. #endif
  83.         
  84.                 // check if the socket numbers match
  85.             if (((UInt8)portRecord->fSlotID[0] - '0') != socketNum)
  86.             {
  87. #if DEBUG
  88.                 DebugStr("\p socketNum - no match");                    
  89. #endif
  90.                 continue;
  91.             }
  92. #if DEBUG
  93.             DebugStr("\p socketNum - matches");                    
  94. #endif
  95.                 
  96.                 // check if the port is offlined
  97.             if (portRecord->fPortFlags && kOTPortIsOffline)
  98.             {
  99.                 // we've found an offline port.  
  100.                 // check if the driver descriptor info matches the info in the port
  101.                 dsi = dd->driverServices.service;
  102.  
  103.                 foundOne = false;
  104.  
  105.                 for (idx = 0; idx < dd->driverServices.nServices; ++idx)
  106.                 {
  107.                     if ( dsi->serviceCategory == kServiceCategoryOpenTransport )
  108.                     {
  109.                         foundOne = true;
  110.                         break;
  111.                     }
  112.                     dsi += 1;
  113.                 }
  114.                 
  115.                 if (foundOne == true)
  116.                 {
  117.                         // check if the driver name matches
  118.                     if (OTMemcmp(&(dd->driverOSRuntimeInfo.driverName[1]), portRecord->fModuleName,
  119.                                     dd->driverOSRuntimeInfo.driverName[0]) == true)
  120.                     {
  121. #if DEBUG
  122.                         DebugStr("\p matching offline port found");                    
  123. #endif
  124.                             // restore the fPortFlags
  125.                         portRecord->fPortFlags &= ~(kOTPortIsOffline + kOTPortIsUnavailable );
  126.                         
  127.                             // set the fContext field to the current deviceRef
  128.                         *(RegEntryID *)portRecord->fContext = *deviceRef;
  129.                         err = SetPortConfiguredProperty(deviceRef);
  130.                         if (err)
  131.                         {
  132. #if DEBUG
  133.                             DebugStr("\p RegistryPropertySet for port-configured property failed");
  134. #endif
  135.                         }    
  136.                         return true;
  137.                     }
  138.                 }
  139.             }
  140.         }
  141.     }
  142. #if DEBUG
  143.     DebugStr("\p matching offliner port not found");
  144. #endif
  145.     
  146.     return false;
  147.  
  148. }
  149.  
  150. /*
  151.     The OfflineThePort call is used to offline a port
  152.     where the assumption is that the deviceRef for the device
  153.     in the NameRegistry is stored in the fContext field of the
  154.     portRecord.  This routine searches the ports for an entry which
  155.     has a matching deviceRef value and unregisters the port.
  156.     
  157.     Assumes that there is an existing port that has as it's fContext
  158.     value, the same as *deviceRef, so that the value can be matched.
  159. */
  160. extern void OfflineThePort(RegEntryID *deviceRef)
  161. {
  162.     RegEntryID        *portContext;
  163.     TPortRecord        *portRecord;
  164.     UInt32            index;
  165.     UInt32            busType;
  166.     
  167.  
  168. #if DEBUG
  169.     DebugStr("\p about to check bus");
  170. #endif
  171.  
  172.     index = 0;
  173.     while (portRecord = OTGetIndexedPort(index))
  174.     {
  175.         index++;
  176.         busType = OTGetBusTypeFromPortRef(portRecord->fRef);
  177.         if (busType == kOTPCCardBus)
  178.         {
  179.                 // check if the deviceRef matches
  180.             portContext = portRecord->fContext;
  181.             if (*((long*)deviceRef) == *((long*)portContext))
  182.             {
  183.                     // set the offline bit in the fPortFlags field
  184.                 portRecord->fPortFlags |= kOTPortIsOffline;
  185.                 portRecord->fPortFlags |= kOTPortIsUnavailable;
  186. #if DEBUG
  187.                 DebugStr("\p port offlined");
  188. #endif
  189.                 return;
  190.             }
  191.         }
  192.     }
  193. #if DEBUG
  194.     DebugStr("\p port not found to offline");
  195. #endif
  196. }
  197.  
  198. /*
  199.     The RegisterThePort call is used to register a network port for a 
  200.     PC Card 3.0 device with Open Transport.  The call 
  201.     is designed for alternate networking cards like TokenRing, and ATM
  202.     which are not handled by the default PC Card Port Scanner.
  203.     
  204.     This function checks for the presence of a 
  205.     "driver-descriptor" and the "SocketNumber" property associated with
  206.     the device node. It uses the these properties to fill in the port information.
  207.     
  208.     The call looks at the "driver-descriptor" property to know how to fill out the 
  209.     TPortRecord structure.
  210.     
  211. */
  212. void RegisterThePort( RegEntryID *deviceRef)
  213. {
  214.     char                buffer[sizeof(DriverDescription) + 
  215.                                  kMaxServices*sizeof(DriverServiceInfo)];
  216.     DriverDescription    *dd = (DriverDescription*)buffer;
  217.     DriverServiceInfo    *dsi;
  218.     OTPortRecord        *portRecord;
  219.     RegEntryID            *portContext;
  220.     OSStatus            err;
  221.     UInt32                size;
  222.     UInt32                framing;
  223.     UInt32                socket;
  224.     size_t                idx;
  225.     size_t                sIndex = 0;
  226.     UInt16                 other;
  227.     UInt16                otType;
  228.     UInt16                 iface;
  229.     Boolean                foundOne;
  230.         
  231. #if    DEBUG    
  232.     DebugStr("\p port scanner:  RegisterThePort");        
  233. #endif
  234.  
  235.     //
  236.     // If the driver has no driver-descriptor property, or the size
  237.     // is too small, or it is too large to fit our buffer - forget 
  238.     // this one.
  239.     //
  240.     err = RegistryPropertyGetSize(deviceRef, kDescriptorProperty, &size);
  241.     if ( err != noErr || size < sizeof(DriverDescription) ||
  242.          size > sizeof(buffer) )
  243.     {
  244. #if DEBUG
  245.         DebugStr("\p kPropertyDriverDesc not found");
  246. #endif
  247.         return;
  248.     }
  249.     
  250.     //
  251.     // Read the driver-descriptor property into our buffer.
  252.     //
  253.     err = RegistryPropertyGet(deviceRef, kDescriptorProperty, buffer, &size);
  254.     
  255.     if ( err != noErr )
  256.     {
  257. #if DEBUG
  258.         DebugStr("\p kPropertyDriverDesc not found");
  259. #endif
  260.         return;
  261.     }
  262.     
  263.     //
  264.     // Read the SocketNumber property into our buffer.
  265.     //
  266.     size = sizeof(socket);
  267.     err = RegistryPropertyGet(deviceRef, kSocketNumber, &socket, &size);
  268.     
  269.     if ( err != noErr )
  270.     {
  271. #if DEBUG
  272.         DebugStr("\p socket property not found");
  273. #endif
  274.         return;
  275.     }
  276.  
  277.     //
  278.     // Check whether an offline port exists for this module
  279.     //
  280.     
  281.     if (OfflinePortExists(deviceRef, dd, socket) == true)
  282.     {
  283.         return;
  284.     }
  285.     
  286.     dsi = dd->driverServices.service;
  287.     foundOne = false;
  288.     
  289.     for (idx = 0; idx < dd->driverServices.nServices; ++idx)
  290.     {
  291.         if ( dsi->serviceCategory == kServiceCategoryOpenTransport )
  292.         {
  293.             foundOne = true;
  294.             break;
  295.         }
  296.         dsi += 1;
  297.     }
  298.     
  299.     if (foundOne == false)
  300.         return;
  301.         
  302.         // check if there is a driver name
  303.     if (dd->driverOSRuntimeInfo.driverName[0] == 0 )
  304.         return;
  305.         
  306.         // lets register this port - first get some memory
  307.     portRecord = (OTPortRecord*)OTAllocPortMem(sizeof(OTPortRecord));
  308.     if (portRecord == nil)
  309.         return;
  310.         
  311.     OTMemzero(portRecord, sizeof(OTPortRecord));
  312.         
  313.     OTMemcpy(&portRecord->fModuleName, &dd->driverOSRuntimeInfo.driverName[1], 
  314.                 dd->driverOSRuntimeInfo.driverName[0]);
  315.     
  316.     otType = (UInt16)((dsi->serviceType >> 16) & 0x7ff);
  317.     iface = (UInt16)(dsi->serviceType & 3);
  318.     framing = (UInt32)((dsi->serviceType >> 8) & 0xff);
  319.     
  320.         // find a unique "other" value for this device
  321.     other = 0;
  322.     do
  323.     {
  324.         portRecord->fRef = OTCreatePortRef(kOTPCCardBus, otType, socket, other++);
  325.     } while ( OTFindPortByRef(portRecord->fRef) != 0 );
  326.     
  327.         // now set the associated slot 
  328. //    portRecord->fSlotID[0] = 0;
  329.  
  330.     OTMemcpy(&portRecord->fSlotID, " \0", 2);
  331.     portRecord->fSlotID[0] = (char)('0'+ socket);
  332.     
  333.         // for the fInfoFlag the 0x1 indicates the module is DLPI
  334.         // for a TPI interface, set the value to 0x2
  335.  
  336.     portRecord->fInfoFlags        = iface;
  337.     portRecord->fCapabilities    = framing;
  338.     portRecord->fNumChildPorts    = 0;
  339.     portRecord->fPortName[0]    = 0;
  340.     
  341.         // allocate port context memory
  342.     portContext = (RegEntryID*)OTAllocPortMem(sizeof(RegEntryID));
  343.     if (portContext != nil)
  344.     {
  345.             // store the deviceRef in the portContext field so that
  346.             // we can discriminate this port entry later when we for a matching 
  347.             // port to offline.
  348.         *portContext = *deviceRef;
  349.         
  350. #if DEBUG
  351.         DebugStr("\p about to register port");
  352. #endif
  353.         err = OTRegisterPort(portRecord, (void*)portContext);
  354.     
  355.         if (err == noErr)
  356.         {
  357.             err = SetPortConfiguredProperty(deviceRef);
  358.             if (err)
  359.             {
  360. #if DEBUG
  361.                 DebugStr("\p RegistryPropertySet for port-configured property failed");
  362. #endif
  363.             }    
  364.         }
  365.         else
  366.         {
  367. #if DEBUG
  368.             DebugStr("\p OTRegisterPort failed");
  369. #endif
  370.         }
  371.     }
  372.     else
  373.     {
  374. #if DEBUG
  375.             DebugStr("\p OTAllocPortMem failed");
  376. #endif
  377.             OTFreePortMem(portRecord);
  378.     }
  379. }
  380.  
  381. static OSStatus SetPortConfiguredProperty (RegEntryID *deviceRef)
  382. {
  383.     OSStatus    err;
  384.     UInt16        portConfigProperty = 1;
  385.  
  386.     // modify the port-configured property to indicate that we have registered the
  387.     // port.  Note that the presence of this property tells the default PC Card
  388.     // Port scanner that the port has been previously registered, whatever the
  389.     // value.  This scanner checks the value and if zero, registers the port.
  390.     // then we set the value to 1 to indicate that we've registered it.  Later
  391.     // we might find this port and have a way to know that we've already configured
  392.     // this device.
  393.     err = RegistryPropertySet(deviceRef, kPortConfigured, 
  394.                             &portConfigProperty, sizeof(portConfigProperty));
  395.     return err;
  396. }
  397.  
  398. #pragma export off